package com.hezhiqin.netty.im.server.processor;

import com.alibaba.fastjson.JSONObject;
import com.hezhiqin.netty.im.protocol.IMDecoder;
import com.hezhiqin.netty.im.protocol.IMEncoder;
import com.hezhiqin.netty.im.protocol.IMMessage;
import com.hezhiqin.netty.im.protocol.IMP;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.GlobalEventExecutor;


/**
 * @program: homeWork
 * @description:
 * @author: hezhiqin
 * @create: 2020-01-06 14:32
 */
public class MsgProcessor {

    //容器
    private  static ChannelGroup onlineUser = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);


    //定义一些扩展属性
    public static final AttributeKey<String> NICK_NAME = AttributeKey.valueOf("nickName");
    public static final AttributeKey<String> IP_ADDR = AttributeKey.valueOf("ipAddr");
    public static final AttributeKey<JSONObject> ATTRS = AttributeKey.valueOf("attrs");
    public static final AttributeKey<String> FROM = AttributeKey.valueOf("from");

    private IMDecoder decode =new IMDecoder();

    private IMEncoder encoder = new IMEncoder();

    public  void processor(Channel channel, IMMessage imMessage){
        processor(channel,encoder.encode(imMessage));
    }

    public  void processor(Channel request, String imMessage){
        //统一在这里处理逻辑
        IMMessage message =  decode.decode(imMessage);

        if (message ==null) return;
        String addr = getAddress(request);

        if (message.getCmd().equals(IMP.LOGIN.getName())){
            //保存用户信息
            //昵称
            request.attr(NICK_NAME).getAndSet(message.getSender());
            //保存用户名IP地址
            request.attr(IP_ADDR).getAndSet(addr);
            //终端类型
            request.attr(FROM).getAndSet(message.getTerminal());
            onlineUser.add(request);

            //通知所有的在线用户。谁上线了
            for (Channel channel : onlineUser) {
                boolean isself = (channel == request);
                if(!isself){
                    message = new IMMessage(IMP.SYSTEM.getName(), sysTime(), onlineUser.size(), getNickName(request) + "加入");
                }else{
                    message = new IMMessage(IMP.SYSTEM.getName(), sysTime(), onlineUser.size(), "已与服务器建立连接！");
                }

                if("Console".equals(channel.attr(FROM).get())){
                    channel.writeAndFlush(request);
                    continue;
                }
                String content = encoder.encode(message);
                channel.writeAndFlush(new TextWebSocketFrame(content));
            }
        }else  if (message.getCmd().equals(IMP.CHAT.getName())){
            for (Channel channel : onlineUser) {
                boolean isself = (channel == request);
                if (isself) {
                    message.setSender("you");
                }else{
                    message.setSender(getNickName(request));
                }
                message.setTime(sysTime());

                if("Console".equals(channel.attr(FROM).get()) & !isself){
                    channel.writeAndFlush(request);
                    continue;
                }
                String content = encoder.encode(message);
                channel.writeAndFlush(new TextWebSocketFrame(content));
            }
        }else  if (message.getCmd().equals(IMP.FLOWER.getName())){
            JSONObject attrs = getAttrs(request);
            long currTime = sysTime();
            if(null != attrs){
                long lastTime = attrs.getLongValue("lastFlowerTime");
                //60秒之内不允许重复刷鲜花
                int secends = 10;
                long sub = currTime - lastTime;
                if(sub < 1000 * secends){
                    message.setSender("you");
                    message.setCmd(IMP.SYSTEM.getName());
                    message.setContent("您送鲜花太频繁," + (secends - Math.round(sub / 1000)) + "秒后再试");

                    String content = encoder.encode(message);
                    request.writeAndFlush(new TextWebSocketFrame(content));
                    return;
                }
            }

            //正常送花
            for (Channel channel : onlineUser) {
                if (channel == request) {
                    message.setSender("you");
                    message.setContent("你给大家送了一波鲜花雨");
                    setAttrs(request, "lastFlowerTime", currTime);
                }else{
                    message.setSender(getNickName(request));
                    message.setContent(getNickName(request) + "送来一波鲜花雨");
                }
                message.setTime(sysTime());

                String content = encoder.encode(message);
                channel.writeAndFlush(new TextWebSocketFrame(content));
            }
        }else  if (message.getCmd().equals(IMP.LOGOUT.getName())){

        }

    }


    /**
     * 获取用户远程IP地址
     * @param client
     * @return
     */
    public String getAddress(Channel client){
        return client.remoteAddress().toString().replaceFirst("/","");
    }


    /**
     * 获取系统时间
     * @return
     */
    private Long sysTime(){
        return System.currentTimeMillis();
    }


    /**
     * 获取用户昵称
     * @param client
     * @return
     */
    public String getNickName(Channel client){
        return client.attr(NICK_NAME).get();
    }


    /**
     * 获取扩展属性
     * @param client
     * @return
     */
    public JSONObject getAttrs(Channel client){
        try{
            return client.attr(ATTRS).get();
        }catch(Exception e){
            return null;
        }
    }

    /**
     * 获取扩展属性
     * @param client
     * @return
     */
    private void setAttrs(Channel client,String key,Object value){
        try{
            JSONObject json = client.attr(ATTRS).get();
            json.put(key, value);
            client.attr(ATTRS).set(json);
        }catch(Exception e){
            JSONObject json = new JSONObject();
            json.put(key, value);
            client.attr(ATTRS).set(json);
        }
    }
}
